package com.yk.auth.controller;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.RandomUtil;
import com.yk.auth.param.*;
import com.yk.auth.service.SysLoginService;
import com.yk.common.core.constant.Constants;
import com.yk.common.core.constant.NumberConstant;
import com.yk.common.core.domain.Result;
import com.yk.common.core.enums.DeviceType;
import com.yk.common.core.utils.CaptchaCodeKeyUtils;
import com.yk.common.core.utils.LoginHelper;
import com.yk.common.core.utils.SendUtils;
import com.yk.common.redis.service.RedisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 登录控制器 yk-auth
 *
 * @author lmx
 * @module 设备管家
 * @date 2023/10/17 11:48
 */
@Slf4j
@Api(tags = "登录控制器")
@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
public class TokenController {

    private final SysLoginService sysLoginService;
    private final RedisService redisService;
    private final SendUtils sendUtils;
    @Value("${sms.alibaba.templateId}")
    private String templateId;

    /**
     * 短信验证码
     */
    @ApiOperation(value = "短信验证码", notes = "类型 0-登录 1-注册 2-忘记密码 3-修改手机号 4-修改密码 6-小程序登录")
    @GetMapping("/code")
    public Result<Void> smsCaptcha(@NotBlank(message = "手机号不能为空") String phone, @NotBlank(message = "类型不能为空") Integer type) {
        Validator.validateMobile(phone, "手机号格式不正确");
        String key = CaptchaCodeKeyUtils.getCaptchaKey(type);
        if (CharSequenceUtil.isEmpty(key)) {
            return Result.fail("类型错误");
        }
        key += phone;
        String code = RandomUtil.randomNumbers(NumberConstant.SIX);
        sendUtils.sendAlibabaSms(phone, code, templateId);
        redisService.setCacheObject(key, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        return Result.ok();
    }

    @ApiOperation("账号密码登录")
    @PostMapping("login")
    public Result<String> login(@Validated @RequestBody LoginBody form) {
        return Result.data(sysLoginService.login(form, DeviceType.PC));
    }

    @ApiOperation("短信登录")
    @PostMapping("/smsLogin")
    public Result<String> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) {
        return Result.data(sysLoginService.smsLogin(smsLoginBody, DeviceType.PC));
    }

    @ApiOperation("用户退出")
    @DeleteMapping("logout")
    public Result<Void> logout() {
        try {
            Long userId = LoginHelper.getLoginUserId();
            if (Objects.isNull(userId)) {
                return Result.ok();
            }
        } catch (Exception e) {
            return Result.ok();
        }
        sysLoginService.logout();
        return Result.ok();
    }

    @ApiOperation("用户注册")
    @PostMapping("register")
    public Result<Void> register(@RequestBody RegisterBody registerBody) {
        sysLoginService.register(registerBody);
        return Result.ok();
    }

    @ApiOperation("忘记密码")
    @PostMapping("forgotPassword")
    public Result<Void> forgotPassword(@RequestBody ForgotPasswordBody forgotPasswordBody) {
        forgotPasswordBody.setCodeType(NumberConstant.TWO);
        sysLoginService.forgotPassword(forgotPasswordBody);
        return Result.ok();
    }

    @ApiOperation("修改手机号")
    @PostMapping("updatePhone")
    public Result<Void> updatePhone(@RequestBody UpdatePhoneBody body) {
        sysLoginService.updatePhone(body);
        return Result.ok();
    }

    @ApiOperation("小程序-修改手机号")
    @PostMapping("updateAppPhone")
    public Result<Void> updateAppPhone(@RequestBody UpdateAppPhoneBody body) {
        sysLoginService.updateAppPhone(body);
        return Result.ok();
    }

    @ApiOperation("修改密码")
    @PostMapping("updatePassword")
    public Result<Void> updatePassword(@RequestBody ForgotPasswordBody forgotPasswordBody) {
        // 验证手机号
        forgotPasswordBody.setCodeType(NumberConstant.FOUR);
        sysLoginService.forgotPassword(forgotPasswordBody);
        sysLoginService.logout();
        return Result.ok();
    }
}
